package ch6.part2;

/**
 * BitMap的数据结构原理
 * 可参照JDK中的BitSet、Redis中的Bitmap实现
 *
 * @author liuwanxiang
 * @version 2019/06/17
 */
public class MyBitMap {

    private int size;
    private long[] words;

    private MyBitMap(int size) {
        this.size = size;
        this.words = new long[(getWordIndex(size - 1) + 1)];
    }

    /**
     * 把位图中的某一位置为真值
     *
     * @param bitIndex 位下标
     */
    private void setBit(int bitIndex) {
        if (bitIndex < 0 || bitIndex > size - 1) {
            throw new IndexOutOfBoundsException("BitMap index out of bound~");
        }
        int wordIndex = getWordIndex(bitIndex);
        words[wordIndex] |= 1L << bitIndex;
    }

    /**
     * 获取位图中，某一点是否为真值
     *
     * @param bitIndex 位下标
     * @return 非零则真
     */
    private boolean getBit(int bitIndex) {
        if (bitIndex < 0 || bitIndex > size - 1) {
            throw new IndexOutOfBoundsException("BitMap index out of bound~");
        }
        int wordIndex = getWordIndex(bitIndex);
        return 0 != (words[wordIndex] & (1L << bitIndex));
    }

    /**
     * 通过传入的索引，检索其在位图中的位置
     *
     * @param bitIndex 索引下标
     * @return word下标
     */
    private int getWordIndex(int bitIndex) {
        return bitIndex >> 6;
    }

    public static void main(String[] args) {
        MyBitMap bitMap = new MyBitMap(128);
        bitMap.setBit(126);
        bitMap.setBit(75);
        System.out.println(bitMap.getBit(126));
        System.out.println(bitMap.getBit(78));
    }

}
